package com.huitone.smspfm.socket.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.socket.core.AbstractMessageHandler;
import com.huitone.smspfm.socket.core.AbstractUserChecker;
import com.huitone.smspfm.socket.core.AppCustomBlockingThreadPool;
import com.huitone.smspfm.socket.core.DefaultMessageHandler;
import com.huitone.smspfm.socket.core.SocketHolder;


/**   
* @Title: SocketServer.java 
* @Package com.huitone.smspfm.socket.server 
* @Description: TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年3月23日 上午10:58:25 
* @version V1.0   
*/
public class SocketServer extends Thread {
	
	private static final Logger logger = LogManager.getLogger(SocketServer.class);
	
	private static SocketServer instance = new SocketServer();
	
	private ServerSocket serverSocket = null;
	
	private ExecutorService executorService = null;
	
	private AbstractMessageHandler messageHandler = null;
	
	private Class<? extends AbstractMessageHandler > exclusiveMessageHandler = null;
	
	private AbstractMessageHandler abstractMessageHandler = null;
	
	private int exclusiveSize = 100;
	
	private AbstractUserChecker userChecker = null;
	
	private int port = 8901;
	
	private int soTimeOut = 600000;
	
	public static SocketServer getInstance() {
		return instance;
	}
	
	private SocketServer() {}
	
	@Override
	public void run() {
		
		executorService = Executors.newFixedThreadPool(SocketHolderManager.getInstance().getMaxActive() + 10);
		
		try {
			serverSocket = new ServerSocket(port);
		} catch (IOException e1) {
			logger.error("创建ServerSocket服务时发生异常,服务退出", e1);
			return;
		}
		
		while(!this.isInterrupted()) {
			
			Socket accept = null;
			
			try {
				accept = serverSocket.accept();
				accept.setTcpNoDelay(true);
				accept.setReceiveBufferSize(64*1024);
			} catch (SocketException e) {
				if (StringUtils.equals("Socket closed", e.getMessage())) {
					logger.info("ServerSocket服务关闭退出");
				} else {
					logger.error("ServerSocket服务发生异常,服务退出", e);
				}
				break;
			} catch (Exception e) {
				logger.error("ServerSocket服务发生异常,服务退出", e);
				break;
			}
			
			String hostName = accept.getInetAddress().getHostName();
			logger.debug("ServerSocket服务收到连接请求,目标IP:" + hostName);
			
			if (exclusiveMessageHandler != null) {
				try {
					abstractMessageHandler = exclusiveMessageHandler.newInstance().setExecutorService(AppCustomBlockingThreadPool.newBlockingThreadPool(exclusiveSize));
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			} else {
				abstractMessageHandler = messageHandler;
			}
			
			SocketHolder socketHolder = new SocketHolder(accept, userChecker, abstractMessageHandler != null ? abstractMessageHandler : new DefaultMessageHandler());
			socketHolder.setSoTimeOut(soTimeOut);
			executorService.execute(socketHolder);
			
		}
		
		if (executorService != null) {
			executorService.shutdown();
		}
		
		if (serverSocket != null) {
			try {
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		if (abstractMessageHandler != null) {
			abstractMessageHandler.shutdown();
		}
		
		if (messageHandler != null) {
			messageHandler.shutdown();
		}
	}

	public AbstractMessageHandler getMessageHandler() {
		return messageHandler;
	}

	public SocketServer setMessageHandler(AbstractMessageHandler messageHandler) {
		this.messageHandler = messageHandler;
		return this;
	}

	public int getMaxActive() {
		return SocketHolderManager.getInstance().getMaxActive();
	}

	public SocketServer setMaxActive(int maxActive) {
		SocketHolderManager.getInstance().setMaxActive(maxActive);
		return this;
	}

	public int getPort() {
		return port;
	}

	public SocketServer setPort(int port) {
		this.port = port;
		return this;
	}

	@Override
	public synchronized void start() {
		
		if (!this.isAlive()) {
			super.start();
		} else {
			logger.warn("SocketServer服务正在运行,不需要重复启动。");
		}
	}

	public SocketServer setSoTimeOut(int soTimeOut) {
		this.soTimeOut = soTimeOut;
		return this;
	}
	
	public void shutdown() {
		
		if (serverSocket != null) {
			try {
				serverSocket.close();
				serverSocket = null;
			} catch (IOException e) {
				logger.error("ServerSocket关闭时异常:", e);
			}
		}
		
		SocketHolderManager.getInstance().shutdown();
		
	}
	
	public AbstractUserChecker getUserChecker() {
		return userChecker;
	}

	public SocketServer setUserChecker(AbstractUserChecker userChecker) {
		this.userChecker = userChecker;
		return this;
	}

	public Class<? extends AbstractMessageHandler> getExclusiveMessageHandler() {
		return exclusiveMessageHandler;
	}

	public SocketServer setExclusiveMessageHandler(Class<? extends AbstractMessageHandler> exclusiveMessageHandler) {
		this.exclusiveMessageHandler = exclusiveMessageHandler;
		return this;
	}

	public int getExclusiveSize() {
		return exclusiveSize;
	}

	public SocketServer setExclusiveSize(int exclusiveSize) {
		this.exclusiveSize = exclusiveSize;
		return this;
	}
}
